package com.yunwaikeji.gy_tool_library.utils.picture.download;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.text.TextUtils;
import android.view.View;
import android.widget.ImageView;

import androidx.fragment.app.Fragment;

import com.yunwaikeji.gy_tool_library.compress.picture.GYCompressPictureCallback;
import com.yunwaikeji.gy_tool_library.utils.GYEncodeUtils;
import com.yunwaikeji.gy_tool_library.utils.display.GYDisplayUtils;
import com.yunwaikeji.gy_tool_library.utils.file.copy.GYFileCopyCallback;
import com.yunwaikeji.gy_tool_library.utils.file.GYFileLoadListener;
import com.yunwaikeji.gy_tool_library.utils.file.GYFileUtils;
import com.yunwaikeji.gy_tool_library.utils.http.GYHttpUtils;

import com.yunwaikeji.gy_tool_library.utils.GYUtils;
import com.yunwaikeji.gy_tool_library.compress.picture.GYCompressPicture;
import com.yunwaikeji.gy_tool_library.view.GYImageView;

import java.io.File;

public class GYPictureBuilder<T> extends GYPictureBase {
    private final Context context;
    private final Activity activity;
    private final Fragment fragment;
    private final View view;
    private GYPictureModel pictureModel;
    private GYLoadListener loadListener;
    private GYCompletedListener completedListener;
    private GYErrorListener errorListener;
    private GYFinishListener finishListener;
    private final String cacheDirectoryPath;
    private ImageView imageView;
    private GYImageView gyImageView;
    private File downFile;
    private File cacheFile;
    private Drawable startDrawable;//加载前图片
    private Drawable loadingDrawable;//加载中图片
    private Drawable errorDrawable;//加载失败图片
    private long cacheMaxSize = -1;//缓存图片最大大小
    private int loadCacheSize = 100 * 1024;//加载图片的缓存大小，默认100kb
    private boolean useCache = true;//是否使用原文件缓存
    private boolean useCompressCache = true;//是否使用压缩缓存

    public GYPictureBuilder(Context context, Activity activity, Fragment fragment, View view, GYPictureModel pictureModel) {
        this.context = context;
        this.activity = activity;
        this.fragment = fragment;
        this.view = view;
        this.pictureModel = pictureModel;
        cacheDirectoryPath = pictureModel.getCachePath();
    }

    public GYPictureBuilder<T> setLoadListener(GYLoadListener loadListener) {
        this.loadListener = loadListener;
        return this;
    }

    public GYPictureBuilder<T> setCompletedListener(GYCompletedListener completedListener) {
        this.completedListener = completedListener;
        return this;
    }

    public GYPictureBuilder<T> setErrorListener(GYErrorListener errorListener) {
        this.errorListener = errorListener;
        return this;
    }

    public GYPictureBuilder<T> setFinishListener(GYFinishListener finishListener) {
        this.finishListener = finishListener;
        return this;
    }

    public Drawable getStartDrawable() {
        return startDrawable;
    }

    public GYPictureBuilder<T> setStartDrawable(Drawable startDrawable) {
        this.startDrawable = startDrawable;
        return this;
    }

    public Drawable getLoadingDrawable() {
        return loadingDrawable;
    }

    public GYPictureBuilder<T> setLoadingDrawable(Drawable loadingDrawable) {
        this.loadingDrawable = loadingDrawable;
        return this;
    }

    public Drawable getErrorDrawable() {
        return errorDrawable;
    }

    public GYPictureBuilder<T> setErrorDrawable(Drawable errorDrawable) {
        this.errorDrawable = errorDrawable;
        return this;
    }

//    public GYPictureBuilder<T> setCacheDirectory(String cacheDirectoryPath) {
//        this.cacheDirectoryPath = cacheDirectoryPath;
//        return this;
//    }
//    public GYPictureBuilder<T> setCacheDirectory(File cacheDirectoryPath) {
//        return setCacheDirectory(cacheDirectoryPath.getPath());
//    }

//    public GYPictureBuilder<T> load(String url) {
//        pictureModel = new GYPictureModel().setUrl(url);
//        return this;
//    }
//
//    public GYPictureBuilder<T> load(File file) {
//        pictureModel = new GYPictureModel().setFile(file);
//        return this;
//    }
//
//    public GYPictureBuilder<T> load(Drawable drawable) {
//        pictureModel = new GYPictureModel().setDrawable(drawable);
//        return this;
//    }
//
//    public GYPictureBuilder<T> load(Bitmap bitmap) {
//        pictureModel = new GYPictureModel().setBitmap(bitmap);
//        return this;
//    }
//
//    public GYPictureBuilder<T> load(Integer resId) {
//        pictureModel = new GYPictureModel().setResId(resId);
//        return this;
//    }
//
//    public GYPictureBuilder<T> load(Uri uri) {
//        pictureModel = new GYPictureModel().setUri(uri);
//        return this;
//    }

    public void into(ImageView imageView) {
        this.imageView = imageView;
        start();
    }

    public void into(GYImageView gyImageView) {
        this.gyImageView = gyImageView;
        start();
    }

    private GYPictureAsListener<Bitmap> bitmapGYPictureAsListener;

    public GYPictureBuilder<T> asBitmap(GYPictureAsListener<Bitmap> pictureAsListener) {
        bitmapGYPictureAsListener = pictureAsListener;
        return start();
    }

    private GYPictureAsListener<Drawable> drawableGYPictureAsListener;

    public GYPictureBuilder<T> asDrawable(GYPictureAsListener<Drawable> pictureAsListener) {
        drawableGYPictureAsListener = pictureAsListener;
        return start();
    }

    private GYPictureAsListener<File> fileGYPictureAsListener;

    public GYPictureBuilder<T> asFile(GYPictureAsListener<File> pictureAsListener) {
        fileGYPictureAsListener = pictureAsListener;
        return start();
    }

    private GYPictureBuilder<T> start() {
        String url = pictureModel.getUrl();
        if (!TextUtils.isEmpty(url)) {
            File file = new File(url);
            if (file.exists()) {
                loadFile(file);
            } else {
                loadUrl(url);
            }
        }

        File oldFile = pictureModel.getFile();
        if (oldFile != null) {
            loadFile(oldFile);
        }

        Drawable drawable = pictureModel.getDrawable();
        if (drawable != null) {
            setImageView(drawable);
        }

        Integer resId = pictureModel.getResId();
        if (!GYUtils.isNullOrEmpty(resId)) {
            setImageView(context.getResources().getDrawable(resId));
        }

        Uri uri = pictureModel.getUri();
        if (uri != null) {
            loadFile(new File(uri.getPath()));
        }
        return this;
    }

    private void loadUrl(String url) {
        initFile(url);
        if (downFile.exists()) {
            loadCache();
        } else {
            GYHttpUtils
                    .newDownloadTask()
                    .setHttpModel(GYHttpUtils.newDownloadModel()
                            .setDownloadDirectory(cacheDirectoryPath)
                            .setCacheDirectory(cacheDirectoryPath)
                            .setUrl(url)
                            .setName(getDownName(url))
                            .setCacheSize(loadCacheSize))
                    .setFileLoadListener(new GYFileLoadListener() {
                        @Override
                        public void start() {
                            setImageView(startDrawable);
                        }

                        @Override
                        public void paused() {

                        }

                        @Override
                        public void stop() {

                        }

                        @Override
                        public void loading(long nowBytes, long totalBytes, long secondBytes) {
                            if (loadListener != null) {
                                loadListener.loading(nowBytes, totalBytes, secondBytes);
                            }
                            setImageView(loadingDrawable);
                        }

                        @Override
                        public void success(String file) {
                            loadCache();
                        }

                        @Override
                        public void error(String error) {
                            downFile.delete();
                            cacheFile.delete();
                            setImageView(errorDrawable);
                            if (completedListener != null) {
                                completedListener.completed(downFile, cacheFile);
                            }
                        }

                        @Override
                        public void finish() {
                        }
                    })
                    .start();
        }
    }

    private void loadFile(File oldFile) {
        initFile(oldFile.getPath());
        if (!oldFile.exists()) {
            return;
        }
        if (downFile.exists()) {
            loadCache();
        } else {
            GYFileUtils.newCopyBuilder()
                    .setOldFile(oldFile)
                    .setNewFile(downFile)
                    .setFileCopyCallback(new GYFileCopyCallback() {
                        @Override
                        public void success(File oldFile, File newFile) {
                            loadCache();
                        }

                        @Override
                        public void error(String error) {
                            showError(error);
                        }
                    })
                    .build();
        }
    }

    private String getCacheFilePath(String path) {
        return cacheDirectoryPath + File.separator + getCacheName(path);
    }

    private String getDownFilePath(String path) {
        return cacheDirectoryPath + File.separator + getDownName(path);
    }

    private void loadCache() {
        if (cacheFile.exists()) {
            Bitmap bitmap = GYDisplayUtils.getBitmap(cacheFile.getPath());
            if (imageView != null) {
                imageView.setImageBitmap(bitmap);
            }
            if (gyImageView != null) {
                gyImageView.getImageBuilder()
                        .setImageDrawable(new BitmapDrawable(bitmap))
                        .build();
            }
            if (completedListener != null) {
                completedListener.completed(downFile, cacheFile);
            }
            if (bitmapGYPictureAsListener != null) {
                bitmapGYPictureAsListener.pictureAs(GYDisplayUtils.getBitmap(downFile.getPath()), GYDisplayUtils.getBitmap(downFile.getPath()));
            }
            if (drawableGYPictureAsListener != null) {
                drawableGYPictureAsListener.pictureAs(new BitmapDrawable(GYDisplayUtils.getBitmap(downFile.getPath())), new BitmapDrawable(GYDisplayUtils.getBitmap(cacheFile.getPath())));
            }
            if (fileGYPictureAsListener != null) {
                fileGYPictureAsListener.pictureAs(downFile, cacheFile);
            }
        } else {
            Bitmap downBitmap = GYDisplayUtils.getBitmap(downFile.getPath());
            if (downBitmap == null) {
                error("图片下载失败");
                return;
            }
            int width = GYUtils.getWindowWidth(context);
            int height = GYUtils.getWindowHeight(context);
            GYCompressPicture.compress()
                    .setMaxSize(width, height)
                    .setCompressSize(cacheMaxSize)
                    .setPath(downFile)
                    .setCompressPath(cacheFile)
                    .setCompressCallback(new GYCompressPictureCallback() {
                        @Override
                        public void success(File file, Bitmap bitmap) {
                            if (imageView != null) {
                                imageView.setImageBitmap(bitmap);
                            }
                            if (gyImageView != null) {
                                gyImageView.getImageBuilder()
                                        .setImageDrawable(new BitmapDrawable(bitmap))
                                        .build();
                            }
                            asFile(downFile, cacheFile);
                            asBitmap(downBitmap, bitmap);
                            completed(downFile, cacheFile);
                            finish();
                        }

                        @Override
                        public void error(String error) {
                            showError("缓存失败：" + error);
                            completed(downFile, cacheFile);
                            asFile(downFile, cacheFile);
                            finish();
                        }
                    })
                    .build();
        }
    }

    private String getDownName(String path) {
        return GYEncodeUtils.to32MD5(path) + "." + GYFileUtils.getNameBySuffix(path);
    }

    private String getCacheName(String path) {
        return pictureModel.getCacheTab() + "-" + getDownName(path);
    }

    private void completed(File downFile, File cacheFile) {
        if (completedListener != null) {
            completedListener.completed(downFile, cacheFile);
        }
    }

    private GYPictureBuilder<T> showError(String error) {
        error(error);
        if (errorListener != null) {
            errorListener.error(error);
        }
        return this;
    }

    private void finish() {
        if (finishListener != null) {
            finishListener.finish();
        }
    }

    private void asFile(File downFile, File cacheFile) {
        if (fileGYPictureAsListener != null) {
            fileGYPictureAsListener.pictureAs(downFile, cacheFile);
        }
    }

    private void asDrawable(Drawable drawable, Drawable cacheDrawable) {
        if (drawableGYPictureAsListener != null) {
            drawableGYPictureAsListener.pictureAs(drawable, cacheDrawable);
        }
    }

    private void asBitmap(Bitmap bitmap, Bitmap cacheBitmap) {
        if (bitmapGYPictureAsListener != null) {
            bitmapGYPictureAsListener.pictureAs(bitmap, cacheBitmap);
        }
    }

    public GYPictureBuilder<T> setCacheMaxSize(long cacheMaxSize) {
        this.cacheMaxSize = cacheMaxSize;
        return this;
    }

    public long getCacheMaxSize() {
        return cacheMaxSize;
    }

    public GYPictureBuilder<T> setLoadCacheSize(int loadCacheSize) {
        this.loadCacheSize = loadCacheSize;
        return this;
    }

    public int getLoadCacheSize() {
        return loadCacheSize;
    }

    public GYPictureBuilder<T> setUseCache(boolean useCache) {
        this.useCache = useCache;
        return this;
    }

    public boolean isUseCache() {
        return useCache;
    }

    public GYPictureBuilder<T> setUseCompressCache(boolean useCompressCache) {
        this.useCompressCache = useCompressCache;
        return this;
    }

    public boolean isUseCompressCache() {
        return useCompressCache;
    }

    private void initFile(String path) {
        downFile = new File(getDownFilePath(path));
        cacheFile = new File(getCacheFilePath(path));
        if (!useCache) {
            downFile.delete();
        }
        if (!useCompressCache) {
            cacheFile.delete();
        }
    }

    private void setImageView(Drawable drawable) {
        if (imageView != null) {
            imageView.setImageDrawable(drawable);
        }
        if (gyImageView != null) {
            gyImageView.getImageBuilder()
                    .setImageDrawable(drawable)
                    .build();
        }
    }
}
